﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.AccessControl;
using System.Text;
using System.Threading;

namespace Downloader
{
    public class Worker
    {
        string path;

        //string url = "http://112.124.35.69/fr.mp3";

        public Worker()
        {
            //string url = "http://files.cnblogs.com/cnryb/HttpSer.zip";
            string url = "http://cnryb.com/a.zip";
            string path = "a.zip";
            
            using (FileStream fs = new FileStream(
                path,
                FileMode.OpenOrCreate,
                FileAccess.Write,
                FileShare.Read,
                2048,
                FileOptions.RandomAccess
                ))
            {
                //先下载文件的第100个字节到最后
                fs.Seek(100, SeekOrigin.Begin);
                Down(fs, url, 100);

                //下载前100个字节
                fs.Seek(0, SeekOrigin.Begin);
                Down(fs, url, 0, 99);
            }
        }

        public void Down(FileStream fs, string url, int start, int end = -1)
        {
            HttpWebRequest hwr = WebRequest.Create(url) as HttpWebRequest;
            if (end == -1)
                hwr.AddRange(start);
            else
                hwr.AddRange(start, end);
            HttpWebResponse resp = hwr.GetResponse() as HttpWebResponse;
            using (Stream input = resp.GetResponseStream())
            {
                byte[] bs = new byte[2048];
                int count;
                while ((count = input.Read(bs, 0, bs.Length)) != 0)
                {
                    fs.Write(bs, 0, count);
                }
            }
        }

        public Worker(string path)
        {
            FileStream fs = new FileStream(
                path,
                FileMode.OpenOrCreate,
                FileAccess.Write,
                FileShare.Read,
                20480,
                FileOptions.RandomAccess);

            string hello = "hello ";
            string word = "word";

            byte[] b = Encoding.ASCII.GetBytes(hello);
            byte[] w = Encoding.ASCII.GetBytes(word);

            fs.Seek(b.LongLength + 2, SeekOrigin.Begin);
            fs.Write(w, 0, w.Length);

            fs.Seek(0, SeekOrigin.Begin);
            fs.Write(b, 0, b.Length);

            fs.Close();


        }


        public void Init()
        {
            FileInfo fi = new FileInfo(path);
            if (!fi.Exists)
            {
                FileStream fs = fi.Create();
            }

        }
    }

    /*
    public unsafe class Worker
    {
        const int BUFSIZE = 20480;
        #region static
        //用来存储全局AsyncOperation对象生存器的字典
        static HybridDictionary userStateToLifetime;
        static ApplicationException appException;
        [ThreadStatic]
        static StringBuilder sb;
        [ThreadStatic]
        static byte[] buffer;
        [ThreadStatic]
        static byte* nbuffer;
        static Worker()
        {
            userStateToLifetime = new HybridDictionary();
            appException = new ApplicationException("not accepted response");
        }
        #endregion
        #region fields
        
        SendOrPostCallback downloadCompletionCallback;
        SendOrPostCallback downloadPausedCallback;
        SendOrPostCallback downloadDoNothingCallback;
        //CourseFileData cData;
        HttpWebRequest request;
        HttpWebResponse response;
        AutoResetEvent finishedEventHandler;
        ManualResetEvent errorWaitEventHandler;
        Stream stream = null;
        FileStream tempFile = null;
        public Thread thread;
        int errorCount;
        public AsyncOperation async;
        
        #endregion

        /// <summary>
        /// 初始化下载，使得网络连接已经被打开
        /// 本地临时文件也已经准备好
        /// </summary>
        /// <param name="createTmpFile"></param>
        private void InitilizeDownload(string path)
        {

            //设定状态

            request = (HttpWebRequest)WebRequest.Create(path);
            //直接设定偏移量：如果是初次建立，在偏移量0的位置
            if (this.cData.LifetimeStatue == LifetimePosition.Downloading)
                this.request.AddRange((int)this.cData.ReadSize);
            this.cData.LifetimeStatue = LifetimePosition.DownloadCreated;
            this.cData.RunState = RunningStatue.Running;//线程已经开始运行
            request.Timeout = Properties.Settings.Default.ConnectTimeout;
            request.AllowAutoRedirect = true;
            request.Proxy = WebRequest.DefaultWebProxy;
            request.Pipelined = true;
            //获取响应
            this.response = (HttpWebResponse)request.GetResponse();
        }

        private void RegisterForCounter()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj)
            {
                HttpWebRequest pvRequest = WebRequest.Create(Uri.EscapeUriString("http://c.microsoft.com/trans_pixel.asp?source=www&TYPE=PV&p=china_msdn_webcast&uri=china/msdn/webcast/download.aspx")) as HttpWebRequest;
                if (pvRequest != null)
                {
                    try
                    {
                        pvRequest.Pipelined = true;
                        pvRequest.Proxy = WebRequest.DefaultWebProxy;
                        pvRequest.Referer = "http://www.microsoft.com/china/msdn/webcast/download.aspx";
                        pvRequest.UserAgent = "iReaper";
                        pvRequest.Method = WebRequestMethods.Http.Get;
                        pvRequest.GetResponse().Close();
                    }
                    catch { }
                }
                //connect ireaper counter
                //string logUrl = "http://www.ireaper.net/log.aspx?CourseID={0}&UserID={1}&Type={2}";
                //string logPath = null;
                //Guid userID = Properties.Settings.Default.UserID;
                //logPath = string.Format(logUrl, this.cData.Owner.Id, userID.ToString(), this.cData.FileType);
                //HttpWebRequest logRequest = WebRequest.Create(logPath) as HttpWebRequest;
                //if (logRequest != null)
                //{
                //    try
                //    {
                //        logRequest.GetResponse().Close();
                //    }
                //    catch { }

                //}
            }));
        }
        /// <summary>
        /// 验证response的正确性
        /// </summary>
        private void VerifyNetworkResponse()
        {
            //check empty
            if (this.response == null)
                return;
            //check if the content length is minus one
            if (this.response.ContentLength < 0)
            {
                //get response url
                Uri responseUri = this.response.ResponseUri;
                if (responseUri == null)
                    throw appException;
                else//valid response
                {
                    if (responseUri.Scheme.ToLower() == "http")
                    {
                        this.InitilizeDownload(responseUri.AbsoluteUri);
                        if (this.response.ContentLength < 0)
                        {
                            this.response.Close();
                            throw appException;
                        }
                    }
                    else
                        throw appException;
                }
            }
        }

        /// <summary>
        /// 创建本地临时文件
        /// </summary>
        private unsafe void CreateLocalFile()
        {
            //检验reponse
            VerifyNetworkResponse();
            //从网络读文件大小
            this.cData.TotalSize = response.ContentLength;
            ////获取文件名
            Uri responseUri = response.ResponseUri;
            ////取出分段的最后一段
            string[] segments = responseUri.Segments;
            if (segments.Length == 0)
                throw new ApplicationException("Can't get file name from response");
            string fileName = segments[segments.Length - 1];
            this.cData.FileName = fileName;
            //检查目录是否存在
            if (!Directory.Exists(this.cData.RootPath))
            {
                Directory.CreateDirectory(this.cData.RootPath);
            }
            //临时路径
            this.cData.FileName = fileName + ".wb";
            //创建
            FileStream file = null;
            file = new FileStream(this.cData.FilePath, FileMode.Create);
            //设定长度
            file.SetLength(this.cData.TotalSize);
            file.Close();
            this.cData.LifetimeStatue = LifetimePosition.LocalFileCreated;
            //

        }

        /// <summary>
        /// 下载任务的执行体
        /// </summary>
        private void DownloadBody()
        {
            if (!request.HaveResponse)
            { return; }
            //设置状态为运行
            try
            {
                //打开临时文件
                tempFile = new FileStream(this.cData.FilePath,
                                            FileMode.Open,
                                            FileAccess.Write,
                                            FileShare.Read,
                                            BUFSIZE,
                                            FileOptions.RandomAccess);            //设定临时文件偏移
                tempFile.Position = this.cData.ReadSize;
                //创建buffer
                //获取网络流
                stream = response.GetResponseStream();
                stream.ReadTimeout = IReaper.Properties.Settings.Default.ReadTimeout;
                //写入
                int iRead = 0;
                //开始更新数据
                //set flag
                long interval = 0;
                int* iWrite = stackalloc int[1];
                this.cData.LifetimeStatue = LifetimePosition.Downloading;
                this.cData.RunState = RunningStatue.Running;
                System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
                watch.Start();
                while (this.cData.ReadSize < this.cData.TotalSize)
                {
                    Thread.BeginCriticalRegion();
                    // Read and write
                    iRead = stream.Read(buffer, 0, BUFSIZE);
                    tempFile.Write(buffer, 0, iRead);
                    Thread.MemoryBarrier();
                    // mark
                    this.cData.ReadSize += iRead;
                    interval += iRead;
                    long elapse = watch.ElapsedMilliseconds;
                    if (elapse > 1000)
                    {

                        this.cData.Speed = (double)interval / watch.ElapsedMilliseconds;
                        watch.Reset();
                        watch.Start();
                        interval = 0;
                        this.cData.FlushToScreen();
                    }
                    this.errorCount = 0;
                    Thread.EndCriticalRegion();
                }
                watch.Stop();
                //修正状态
                this.cData.LifetimeStatue = LifetimePosition.DownloadFinished;

            }
            finally
            {
                if (tempFile != null)
                {
                    //关闭流
                    this.cData.ReadSize = tempFile.Position;
                    tempFile.Close();
                }
            }
            //修改后缀
            this.ChangeFileExtension();
        }
        
        /// <summary>
        /// 修改后缀
        /// </summary>
        private void ChangeFileExtension()
        {
            //生成目标文件名

            //如果目标文件存在了，直接覆盖

            //重命名

            //删除临时文件

            //重置文件名

            //改变状态
            
            //开始解压缩
        }
    }
     */
}
